package com.example.demo.component;

import com.example.demo.dao.ArticleVisitRecordDao;
import com.example.demo.dao.ArticleVisitTotalDao;
import com.example.demo.model.ArticleVisitRecordModel;
import com.example.demo.model.ArticleVisitTotalModel;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * 定时把访问记录表里面的数据汇总到访客统计表
 * 为什么把每个访问记录利用这样的方案呢？(MQ->Redis List->MQ),
 * 而不是MQ直接处理，这是因为每次有访问进来，单MQ的方式都会至少运行一次DB，如果并发上来啦，MQ就受限于DB的性能。
 * 筛入redis,然后批量写入是最好的方案
 */
@Configuration      //1.主要用于标记配置类，兼备Component的效果。
//@EnableScheduling   // 2.开启定时任务
public class ArticleVisitCountTask {

    @Resource
    ArticleVisitRecordDao articleVisitRecordDao;
    @Resource
    ArticleVisitTotalDao articleVisitTotalDao;

    //3.添加定时任务，统计文章pv
    @Scheduled(cron = "0 0 0/1 * * ?")
    @Transactional
    public void execTask() throws Exception {
        SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        simple.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        System.out.println(simple.format(new Date()) + "：文章访问汇总任务开始执行");
        // 获取id列表
        ArticleVisitRecordModel articleVisitRecordModel = articleVisitRecordDao.getIdsByNotTotal();
        // 如果id列表是空则不继续执行
        if(articleVisitRecordModel == null || articleVisitRecordModel.getIds() == null)
        {
            return;
        }
        // 统计pv的数据列表（根据文章分组）
        List<ArticleVisitTotalModel> articleVisitTotalModelNotTotalList = articleVisitTotalDao.getNotTotalDataGroupArticleList(articleVisitRecordModel);

        String articleIds = "";
        for (ArticleVisitTotalModel articleVisitTotalModel : articleVisitTotalModelNotTotalList)
        {
            articleIds = articleIds.equals("") ? articleIds.concat(String.valueOf(articleVisitTotalModel.getArticle_id()))
                    : articleIds.concat(",").concat(String.valueOf(articleVisitTotalModel.getArticle_id()));
        }
        // 已经存在统计表的文章列表
        List<ArticleVisitTotalModel> articleVisitTotalModelList =  articleVisitTotalDao.getListByArticleIds(articleIds);

        for (ArticleVisitTotalModel articleVisitTotalModel1 : articleVisitTotalModelNotTotalList)
        {
            boolean exitesRecord = false;
            for (ArticleVisitTotalModel articleVisitTotalModel : articleVisitTotalModelList)
            {
                if(articleVisitTotalModel1.getArticle_id().equals(articleVisitTotalModel.getArticle_id()))
                {
                    exitesRecord = true;
                }
            }
            // 更新
            if(exitesRecord)
            {
                if(! articleVisitTotalDao.updatePvById(articleVisitTotalModel1))
                {
                    throw new Exception("更新文章统计失败");
                }
            }else{
                // 写入
                if(! articleVisitTotalDao.add(articleVisitTotalModel1))
                {
                    throw new Exception("写入文章统计失败");
                }
            }
        }

        // 标记访问记录为已统计
        if(! articleVisitRecordDao.updateHasTotalByIds(articleVisitRecordModel.getIds()))
        {
            throw new Exception("更新访问记录失败");
        }
    }

}
